package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"runtime"
)




//net/http 底层解读
//request数据是如何流转的
//
//gin框架到底扮演了什么角色
//
//请求从gin流入net/http, 最后又是如何回到gin中
//
//gin的context为何能承担起来复杂的需求
//
//gin的路由算法
//
//gin的中间件是什么
//
//gin的Engine具体是个什么东西
//
//net/http的requeset, response都提供了哪些有用的东西


func main() {

	r:=  gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK,gin.H{
			"message": "go语言中文文档www.topgoer.com",
		})
	})
	r.Run(":5200")
}

func Test(){
	//http 底层（HTTP是由TCP协议承载的）
	http.HandleFunc("/", func(w http.ResponseWriter,r *http.Request) {
		w.Write([]byte("Hello World"))
	})
	if err := http.ListenAndServe("8000",nil);err!=nil{
		fmt.Println("start http server fail:", err)
	}

}

func Channel()  {
	gin.Default()
	//无缓冲协程
	c := make(chan int)
	go func() {
		for i:=0; i<5; i++ {
			c <- 123
		}
	// 如果不关闭，则会造成死锁（确定没有数据发送了，就进行关闭）
	//向关闭的chan 发送数据出发panic错误
	//关闭chan,还是可以继续从chan里面接收数据
	//对于nil chan,无论收发都会阻塞
		close(c)
	}()
	for  {
		if data,ok := <- c;ok{
			fmt.Println(data)
		}else{
			break
		}
		runtime.Goexit()
	}
   fmt.Println("main close")


}



/**
runtime.GOMAXPROCS(10) :设置G 的数量

线程和协程   （CSP并发模型）
线程：程序执行的最小单元，拥有自己独立的栈独立的堆，共享堆，不共享栈，线程切换由操作系统完成
协程：程序组件，共享堆，不共享栈，协程的切换一般在代码中显式控制（协作任务控制机制）


goroutine 是Go语言中并发的执行单位。有点抽象，其实就是和传统概念上的”线程“类似，可以理解为”线程“。
channel是Go语言中各个并发结构体(goroutine)之前的通信机制。 通俗的讲，就是各个goroutine之间通信的”管道“，有点类似于Linux中的管道。


main 本身就是一个goroutine

内核空间：CPU资源、i/o资源
用户空间：上层应用程序的固定活动空间，不可以直接访问资源


Goexit
退出当前执行的goroutine，但是defer函数还会继续调用
Gosched
让出当前goroutine的执行权限，调度器安排其他等待的任务运行，并在下次某个时候从该位置恢复执行。
NumCPU
返回 CPU 核数量
NumGoroutine
返回正在执行和排队的任务总数
GOMAXPROCS
用来设置可以并行计算的CPU核数的最大值，并返回之前的值。


engine.Run -> http.ListenAndServe -> engine.handleHTTPRequest -> c.Next

Gin路由实现
httprouter(radix-tree)
 */

